import {
	EditFormActionType,
	ICtrlActionResult,
	IDEViewAbility,
	IDEViewStore,
	IEditFormAbility,
	IHttpResponse,
	IOpenViewResult,
	IParam,
	IViewLogicInput,
	IWFDynaEditViewAbility,
	IWFDynaEditViewController,
	IWFDynaEditViewControllerParams,
	IWFDynaEditViewStore,
	WFDynaEditViewActionType,
} from '@/core/interface';
import { AuthUtil, deepCopy, transformDoData, transformRawData } from '@/core/utils';
import { DEViewController } from './de-view-controller';

/**
 * 工作流动态编辑视图
 *
 * @export
 * @class WFEditViewController
 * @extends {DEViewController<WFDynaEditViewActionType, IWFDynaEditViewStore, IWFDynaEditViewAbility>}
 * @implements {IWFEditViewController<IWFDynaEditViewStore, IWFDynaEditViewAbility>}
 */
export class WFEditViewController<
		T,
		S extends IDEViewStore,
		A extends IDEViewAbility
	>
	extends DEViewController<
		WFDynaEditViewActionType,
		IWFDynaEditViewStore,
		IWFDynaEditViewAbility
	>
	implements
		IWFDynaEditViewController<IWFDynaEditViewStore, IWFDynaEditViewAbility>
{
	/**
	 * 工作流附加功能类型映射关系对象
	 *
	 * @protected
	 * @type {*}
	 * @memberof WFEditViewController
	 */
	protected wfAddiFeatureRef: any = {
		reassign: { featureTag: 'REASSIGN', action: 'TransFerTask' },
		addstepbefore: { featureTag: 'ADDSTEPBEFORE', action: 'BeforeSign' },
		sendback: { featureTag: 'SENDBACK', action: 'SendBack' },
		sendcopy: { featureTag: 'SENDCOPY', action: 'sendCopy' },
	};

	/**
	 * 实体服务
	 *
	 * @protected
	 * @type {*}
	 * @memberof WFEditViewController
	 */
	protected appEntityService: any;

	/**
	 * 处理视图初始化
	 *
	 * @protected
	 * @param {IWFEditViewControllerParams<WFDynaEditViewActionType, IWFDynaEditViewAbility>} params
	 * @memberof WFEditViewController
	 */
	protected processViewInit(
		params: IWFDynaEditViewControllerParams<
			WFDynaEditViewActionType,
			IWFDynaEditViewAbility
		>
	) {
		super.processViewInit(params);
		Object.assign(this.store, {
			activeForm: {},
			isEditable: false,
			dynamicToolbar: [],
			actionGroup: null,
			dataInfo: '',
		});
	}

	/**
	 * 获取表单能力
	 *
	 * @protected
	 * @return {*}  {(IEditFormAbility | undefined)}
	 * @memberof WFEditViewController
	 */
	protected getMainCtrlAbility(): IEditFormAbility | undefined {
		if (this.store.activeForm) {
			return this.getSubAbility<IEditFormAbility>(this.store.activeForm.name);
		}
		return undefined;
	}

	/**
	 * 视图挂载
	 *
	 * @param {IParam} [opts={}]
	 * @memberof WFEditViewController
	 */
	public viewMounted(opts: IParam = {}) {
		super.viewMounted(opts);
		if (this.model.useDefaultLayout) {
			if (!this.isLoadDefault) {
				this.isLoadDefault = true;
				return;
			}
			this.getWFLinkModelAndComputeForm().then(() => {
				this.onFormLoad();
			});
		} else {
			this.initLayout().then(async () => {
                if (!this.isLoadDefault) {
                    this.isLoadDefault = true;
                    return;
                }
				await this.getWFLinkModelAndComputeForm();
                this.onFormLoad();
			});
		}
	}

	/**
	 * 计算激活表单
	 *
	 * @protected
	 * @param {(string | null)} formName
	 * @memberof WFEditViewController
	 */
	protected computeActiveForm(formName: string | null) {
		const { dynamicForm } = this.model;
		let activeForm: any = null;
		if (formName) {
			activeForm = dynamicForm.find((form: IParam) => {
				return form.name.toLowerCase() === `wfform_${formName.toLowerCase()}`;
			});
		} else {
			activeForm = dynamicForm.find((form: IParam) => {
				return form.name.toLowerCase() === 'form';
			});
		}
		if (activeForm) {
			this.store.activeForm = activeForm;
		}
	}

	/**
	 * 获取工作流工具栏 and 计算动态表单
	 *
	 * @protected
	 * @param {IParam} [opts={}]
	 * @memberof WFEditViewController
	 */
	protected async getWFLinkModelAndComputeForm() {
		const { viewParams, context } = this.store;
		if (this.model.entityCodeName) {
			this.appEntityService = await App.getDataService(
				this.model.entityCodeName,
				context
			);
		}
		const params: IParam = {};
		if (Object.keys(viewParams).length > 0) {
			Object.assign(params, {
				processDefinitionKey: viewParams.processDefinitionKey,
				taskDefinitionKey:
					viewParams.taskDefinitionKey || viewParams.userTaskId,
			});
		}
		const tempContext = deepCopy(context);
		try {
			const response: IHttpResponse = await this.appEntityService.getWFLink(
				tempContext,
				params
			);
			if (response.success) {
				const data: any = response.config;
				this.store.dynamicToolbar = response.data;
				if (data && data['process-form']) {
					this.computeActiveForm(data['process-form']);
				} else {
					this.computeActiveForm(null);
				}
			}
		} catch (error) {}
	}

	/**
	 * 将待办任务标记为已读
	 *
	 * @protected
	 * @param {IParam} $DO
	 * @memberof WFEditViewController
	 */
	protected async readTask($DO: IParam) {
		const { context } = this.store;
		const tempContext = deepCopy(context);
		try {
			const response: IHttpResponse = await this.appEntityService.ReadTask(
				tempContext,
				$DO
			);
			if (!response.success) {
			}
		} catch (error) {}
	}

	/**
	 * 处理表单加载完成
	 *
	 * @protected
	 * @param {IParam[]} data
	 * @memberof WFEditViewController
	 */
	protected handleFormLoad(data: IParam[]) {
		this.setActionGroup();
		this.handleData(data);
	}

	/**
	 * 设置行为组
	 *
	 * @memberof WFEditViewController
	 */
	protected setActionGroup() {
		const form = this.getMainCtrlAbility();
		if (form) {
			const detailModel = form.getDetailModel();
			Object.values(detailModel).forEach((item: IParam) => {
				if (Object.is(item.detailType, 'GROUPPANEL')) {
					if (item.uIActionGroup) {
						this.store.actionGroup = item.uIActionGroup;
						if (this.store.actionGroup) {
							Object.assign(this.store.actionGroup, {
								name: item.name,
							});
						}
						item.uIActionGroup = undefined;
					}
					return;
				}
			});
		}
	}

	/**
	 * 处理数据
	 *
	 * @protected
	 * @param {IParam[]} data
	 * @memberof WFEditViewController
	 */
	protected async handleData(data: IParam[]) {
		const { viewParams } = this.store;
		const arg = data[0];
		this.store.dataInfo = Object.is(arg.srfuf, '1')
			? this.model.majorPSAppDEField
				? arg[this.model.majorPSAppDEField.toLowerCase()]
				: arg.srfmajortext
			: App.ts("app.common.newlybuild","新建");
		const $DO = arg.$DO;
		if (
			Object.is(viewParams.srfwf, 'toread') ||
			Object.is(viewParams.srfwf, 'todo')
		) {
			Object.assign($DO, { taskId: viewParams.srftaskid });
			await this.readTask($DO);
		}
        AuthUtil.calcToolbarItemState(
			Object.is(arg.srfuf, '0'),
			this.store.toolbarItems
		);
        await this.calcToolbarItemAuthState(arg);
	}

    /**
     * 处理工具栏点击
     *
     * @param {IParam} toolbarItem
     * @memberof WFEditViewController
     */
    public handleToolbarItemClick(event: MouseEvent, logic: IViewLogicInput) {
        const { context, viewParams } = this.store;
        const form = this.getMainCtrlAbility();
        if (form) {
            App.getViewLogicHelper().executeViewLogic(
				context,
				viewParams,
				form.getData(),
				event,
				form,
				logic
			);
        }
    }
    
	/**
	 * 处理行为点击
	 *
	 * @param {MouseEvent} event
	 * @param {IParam} action
	 * @memberof WFEditViewController
	 */
	public handleActionClick(event: MouseEvent, action: IParam) {
		const { context, viewParams } = this.store;
		const logic: IViewLogicInput = {
			name: this.store.actionGroup?.name,
			xDataCtrlName: '',
			actionTag: action.uIActionTag,
			actionDECodeName: action.actionDECodeName,
			predefinedType: action.predefinedType,
		};
		const form = this.getMainCtrlAbility();
		if (form) {
			App.getViewLogicHelper().executeViewLogic(
				context,
				viewParams,
				form.getData(),
				event,
				form,
				logic
			);
		}
	}

	/**
	 * 处理动态工具栏点击
	 *
	 * @param {IParam} toolbarItem 工具栏项
	 * @memberof WFEditViewController
	 */
	public handleDynamicToolbarClick(toolbarItem: IParam) {
		const form = this.getMainCtrlAbility();
		if (form) {
			const data = form.getData();
			const submit = (submitData: IParam[], item: IParam) => {
				form.wfSubmit(submitData, item).then((response: ICtrlActionResult) => {
					if (response.ok) {
						const _data = response.data ? response.data : [];
						if (this.openType === 'ROUTE') {
                            if (App.getProjectSetting().cache) {
                                App.getGlobalNotificationHelper().notice(form.getModel().entityCodeName, 'refresh');
                            }
							this.closeView();
						} else {
							this.emit('viewDataChange', _data);
							this.emit('viewClose', _data);
						}
					}
				});
			};
			const submitAction = () => {
				if (toolbarItem.sequenceflowview) {
					const { viewRef, entityCodeName } = this.model;
					const view = viewRef.find((item: IParam) => {
						return item.name === `WFACTION@${toolbarItem.sequenceflowview}`;
					});
					if (view) {
						const { context } = this.store;
						const tempContext = deepCopy(context);
						if (entityCodeName) {
							Object.assign(tempContext, {
								[entityCodeName.toLowerCase()]: data[0].srfkey,
							});
						}
						const tempViewParams = {
							actionView: toolbarItem.sequenceflowview,
							actionForm: toolbarItem.sequenceflowform,
						};
						const viewConfig = App.getAppViewConfig()?.[view.viewName];
						App.getOpenViewHelper()
							.openModal(viewConfig, tempContext, tempViewParams)
							.then((result: IOpenViewResult) => {
								if (result.ok) {
									const tempSubmitData: any = deepCopy(data[0]);
									if (result.data) {
										const resultData: any = result.data[0];
										if (Object.keys(resultData).length > 0) {
											const tempData: any = {};
											Object.keys(resultData).forEach((key: any) => {
												if (resultData[key] && key !== 'srfuf')
													tempData[key] = resultData[key];
											});
											Object.assign(tempSubmitData, tempData);
										}
									}
									submit([tempSubmitData], toolbarItem);
								}
							});
					}
				} else {
					submit(data, toolbarItem);
				}
			};
			if (toolbarItem.type) {
				if (Object.is(toolbarItem.type, 'finish')) {
					submitAction();
				} else {
					this.handleWFAddiFeature(toolbarItem);
				}
			} else {
				submitAction();
			}
		}
	}

	/**
	 * 处理工作流辅助能力
	 *
	 * @protected
	 * @param {IParam} toolbarItem
	 * @memberof WFEditViewController
	 */
	protected handleWFAddiFeature(toolbarItem: IParam) {
		const featureTag: string =
			this.wfAddiFeatureRef[toolbarItem.type]?.featureTag;
		if (featureTag) {
			const { viewRef, entityCodeName } = this.model;
			const view = viewRef.find((item: IParam) => {
				return item.name === `WFUTILACTION@${featureTag}`;
			});
			const form = this.getMainCtrlAbility();
			if (view && form) {
				const data = form.getData();
				const { context } = this.store;
				const tempContext = deepCopy(context);
				if (entityCodeName) {
					Object.assign(tempContext, {
						[entityCodeName.toLowerCase()]: data[0].srfkey,
					});
				}
				const tempViewParams = {
					actionView: toolbarItem.sequenceflowview,
					actionForm: toolbarItem.sequenceflowform,
				};
				const viewConfig = App.getAppViewConfig()?.[view.viewName];
				App.getOpenViewHelper()
					.openModal(viewConfig, tempContext, tempViewParams)
					.then((result: IOpenViewResult) => {
						if (result.ok) {
							const tempSubmitData: IParam = deepCopy(data[0]);
							if (result.data) {
								const resultData: any = result.data[0];
								if (Object.keys(resultData).length > 0) {
									const tempData: any = {};
									Object.keys(resultData).forEach((key: any) => {
										if (resultData[key] && key !== 'srfuf')
											tempData[key] = resultData[key];
									});
									Object.assign(tempSubmitData, tempData);
								}
							}
							this.submitWFAddiFeature(tempSubmitData, toolbarItem);
						}
					});
			}
		}
	}

	/**
	 * 提交工作流辅助功能
	 *
	 * @protected
	 * @param {IParam[]} submitData
	 * @param {IParam} toolbarItem
	 * @memberof WFEditViewController
	 */
	protected async submitWFAddiFeature(submitData: IParam, toolbarItem: IParam) {
		const tempSubmitData: any = Object.assign(toolbarItem, {
			activedata: transformDoData(submitData),
		});
		const action = this.wfAddiFeatureRef[toolbarItem.type]?.action;
		if (action) {
			const { context } = this.store;
			const tempContext = deepCopy(context);
			Object.assign(tempContext, { taskId: toolbarItem.taskId });
			try {
				const response: IHttpResponse = await this.appEntityService[action](
					tempContext,
					tempSubmitData
				);
				if (response.success) {
					App.getGlobalNotificationHelper().notice('srfwftodo', 'refresh');
					if (this.openType === 'ROUTE') {
						this.closeView();
					} else {
						this.emit('viewDataChange', [response.data]);
						this.emit('viewClose', [response.data]);
					}
					App.getNotificationHelper().success(
						App.ts('app.notificationtitle.success'),
						`${App.ts('widget.editform.workflow.submitsuccess')}！`
					);
				}
			} catch (error) {
				App.getNotificationHelper().error(
					App.ts('app.notificationtitle.error'),
					`${App.ts('widget.editform.workflow.submitsuccess')}！`
				);
			}
		}
	}

	/**
	 * 处理部件行为
	 *
	 * @param {string} name
	 * @param {EditFormActionType} action
	 * @param {IParam[]} data
	 * @memberof WFEditViewController
	 */
	public handleCtrlAction(
		name: string,
		action: EditFormActionType,
		data: IParam[]
	): void {
		super.handleCtrlAction(name, action, data);
		if (action === 'load' || action === 'loadDraft') {
			this.handleFormLoad(data);
		}
	}

	/**
	 * 表单加载
	 *
	 * @protected
	 * @memberof WFDynaActionViewController
	 */
	protected onFormLoad() {
		const form = this.getMainCtrlAbility();
		const { entityCodeName } = this.model;
		let action: 'loadDraft' | 'load' = 'loadDraft';
		if (
			this.model.entityCodeName &&
			this.store.context[this.model.entityCodeName.toLowerCase()]
		) {
			action = 'load';
		}
		if (form && entityCodeName) {
			form[action](deepCopy(this.store.viewParams));
		}
	}

	/**
	 * 处理部件初始化
	 *
	 * @param {string} name
	 * @param {IEditFormAbility} ability
	 * @memberof WFDynaActionViewController
	 */
	public handleCtrlInit(name: string, ability: IEditFormAbility) {
		super.handleCtrlInit(name, ability);
	}
}
